"""
Case Type   : 资源池化
Case Name   : 连续扩容相同节点
Create At   : 2024.10
Owner       : chen
Description :
    1.扩容单个备机
    gs_expansion -U {user} -G {user} -X {xml} -h {ip}
    2.检查扩容情况
    cm_ctl -query -Cv
    查看各节点pg_hba.conf配置文件有无新节点信息
    3.检查数据一致性
    主库：drop table if exists test_table;
    create table test_table(id int, name varchar);
    insert into test_table values(1,'zs')(2, 'ls');
    备库：select * from test_table;
    4.再次执行扩容步骤一中的备节点
    gs_expansion -U {user} -G {user} -X {xml} -h {ip}
    5.恢复环境
    执行缩容；
    恢复集群状态：cm_ctl switchover -a
Expect      :
    1.执行扩容成功
    2.扩容节点加入成功，集群状态正常，配置文件中内容加载成功
    3.主库执行成功；
    备库查询成功
    4.执行失败
    5.缩容成功；
    恢复成功
"""

import os
import unittest
from testcase.utils.Logger import Logger
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from yat.test import Node
from yat.test import macro

class SharedStorage(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        self.pri_node = Node('PrimaryDbUser')
        self.pri_root_node = Node('PrimaryRoot')
        self.sta2_node = Node('Standby2DbUser')
        self.commsh = CommonSH('PrimaryDbUser')
        self.sta2_commsh = CommonSH('Standby2DbUser')
        self.constant = Constant()
        self.db_host = self.sta2_node.db_host
        self.s_user = self.pri_node.ssh_user

    def test_shared_storage(self):
        text = "-----step1: 扩容单个备机 expect: 成功-----"
        self.log.info(text)
        xml_path = macro.DB_XML_PATH
        cmd = f'''gs_expansion -U {self.s_user} \
            -G {self.s_user} -X {xml_path} -h {self.db_host}'''
        execute_cmd = f'''source {macro.DB_ENV_PATH};
            expect <<EOF
            set timeout 300
            spawn {cmd}
            expect "*assword*:"
            send "{self.pri_root_node.ssh_password}\\n"
            expect "*assword*:"
            send "{self.pri_root_node.ssh_password}\\n"
            expect "*lease repeat for database*:"
            send "{macro.GAUSSDB_INIT_USER_PASSWD}\\n"
            expect eof\n''' + '''EOF'''
        self.log.info(execute_cmd)
        res = self.pri_root_node.sh(execute_cmd).result()
        self.log.info(res)
        self.assertIn(f'{self.db_host}:\tSuccess', res)

        text = f'-----step2: 检查扩容情况 expect: 检查成功-----'
        self.log.info(text)
        res = self.commsh.exec_cm_ctl('query', '-Cv')
        self.log.info(res)
        node_arr = res.splitlines()[-1].split('|')
        for node_mes in node_arr:
            self.assertIn('Normal', node_mes)
        cmd = f'''cat {macro.DB_INSTANCE_PATH}/postgresql.conf | grep {self.db_host}'''
        self.log.info(cmd)
        res = self.pri_node.sh(cmd).result()
        self.log.info(res)
        self.assertIn(f'{self.db_host}', res)
        cmd = f'''cat {macro.DB_INSTANCE_PATH}/postgresql.conf | grep {self.pri_node.db_host}'''
        self.log.info(cmd)
        res = self.sta2_node.sh(cmd).result()
        self.log.info(res)
        self.assertIn(f'{self.pri_node.db_host}', res)
        cmd = f'''cat {macro.DB_INSTANCE_PATH}/pg_hba.conf | grep {self.db_host}'''
        self.log.info(cmd)
        res = self.pri_node.sh(cmd).result()
        self.log.info(res)
        self.assertIn(f'{self.db_host}', res)
        cmd = f'''cat {macro.DB_INSTANCE_PATH}/pg_hba.conf | grep {self.pri_node.db_host}'''
        self.log.info(cmd)
        res = self.sta2_node.sh(cmd).result()
        self.log.info(res)
        self.assertIn(f'{self.pri_node.db_host}', res)

        text = "-----step3: 检查数据一致性 expect: 成功-----"
        self.log.info(text)
        res = self.commsh.execut_db_sql(f'''drop table if exists test_table;
            create table test_table(id int, name varchar);
            insert into test_table values(1,'zs'),(2, 'ls');''')
        self.log.info(res)
        self.assertIn(self.constant.TABLE_DROP_SUCCESS, res,
                      '执行失败' + text)
        self.assertIn(self.constant.TABLE_CREATE_SUCCESS, res,
                      '执行失败' + text)
        self.assertIn(self.constant.INSERT_SUCCESS_MSG, res,
                      '执行失败' + text)
        res = self.sta2_commsh.execut_db_sql(f'''select * from test_table;''')
        self.log.info(res)
        self.assertIn('(2 rows)', res, '执行失败' + text)

        text = "-----step4: 再次执行扩容步骤一中的备节点 expect: 成功-----"
        self.log.info(text)
        cmd = f'''gs_expansion -U {self.s_user} \
            -G {self.s_user} -X {xml_path} -h {self.db_host}'''
        execute_cmd = f'''source {macro.DB_ENV_PATH};
            expect <<EOF
            set timeout 300
            spawn {cmd}
            expect "*assword*:"
            send "{self.pri_root_node.ssh_password}\\n"
            expect "*assword*:"
            send "{self.pri_root_node.ssh_password}\\n"
            expect "*lease repeat for database*:"
            send "{macro.GAUSSDB_INIT_USER_PASSWD}\\n"
            expect eof\n''' + '''EOF'''
        self.log.info(execute_cmd)
        res = self.pri_root_node.sh(execute_cmd).result()
        self.log.info(res)
        self.assertIn('Exception: XML configuration failed', res)

    def tearDown(self):
        text = "-----step5: 恢复环境 expect: 成功-----"
        self.log.info(text)
        cmd = f'''source {macro.DB_ENV_PATH};
            expect <<EOF
            set timeout 600
            spawn gs_dropnode -U {self.s_user} -G {self.s_user} \
            -h {self.db_host}
            expect "*drop the target node (yes/no)?*"
            send "yes\\n"
            expect eof\n''' + '''EOF'''
        self.log.info(cmd)
        res = self.pri_node.sh(cmd).result()
        self.log.info(res)
        self.assertIn('Success to drop the target nodes', res)
        res = self.sta2_node.sh(f'source {macro.DB_ENV_PATH}; ' \
            'gs_uninstall --delete-data').result()
        self.log.info(res)
        res = self.commsh.exec_cm_ctl('switchover', '-a')
        self.log.info(res)
        self.log.info(f'-----{os.path.basename(__file__)} end-----')